home *** CD-ROM | disk | FTP | other *** search
- ;========================================================================================
- ;
- ; File: FWLookup.asm
- ; Release Version: $ 1.0d11 $
- ;
- ; Copyright: 1995 by Apple Computer, Inc., all rights reserved.
- ;
- ;========================================================================================
-
- LOCALS ; Yes, we want local symbols on (those prefixed with a @@)
- Model Large ; Large memory model
-
- %NOINCL
- include macros.asm
-
- public _FW_PrivWinGetTaskGlobals, _FW_PrivWinSetTaskGlobals
- extrn ISTASK:far ; FAR PASCAL IsTask(HTASK hTask)
-
- begdata
-
- kMaxTasks = 32
-
- gCachedTaskID DW 0
- gCachedTaskGPtr DD 0
-
- gTaskCount DW 0
- gTaskIDArray DW kMaxTasks DUP (?)
- gTaskPtrArray DD kMaxTasks DUP (?)
-
- enddata
-
- begcode FWLookup
-
- ;========================================================================================
- ; PackTaskTable
- ; Packs the task table, checking for tasks that have terminted
- ; IsTask function is used to check if a task handle is still valid
- ;
- ;========================================================================================
-
- PackTaskTable PROC
-
- WINENTER
-
- mov cx, [gTaskCount]
- jcxz @@doReturn
-
- push SI
- mov SI, OFFSET gTaskIDArray
- cld ; scan forward
-
- ; start the loop
- @@nextTaskID:
- mov AX, [SI] ; get the next task ID
- push AX
- call ISTASK ; check if the task is still valid
- jnz @@doNextTask
-
- ; the current task is not valid, remove the entry
- dec [gTaskCount]
- dec CX
-
- mov DI, [gTaskCount]
- shl DI, 2
-
- mov AX, [DI]
- mov [SI], AX
- mov AX, [DI + 2]
- mov [SI + 2], AX
-
- jmp short @@doLoop ; loop to the next, but don't increment the pointer
-
- ; flush the cache
- mov [gCachedTaskID], 0
-
- @@doNextTask:
- inc SI
- inc SI
- @@doLoop:
- loop @@nextTaskID
-
- pop SI
-
- @@doReturn:
- WINLEAVE
- retf
-
- PackTaskTable ENDP
-
- ;========================================================================================
- ; FW_PrivWinGetTaskGlobals
- ; Returns the global pointer associated with this task
- ;
- ; Parameters:
- ; None
- ;
- ; Return value:
- ; The data pointer associated with the current task
- ; If the current task is not in the table, a new item is allocated
- ; The initial value for the data pointer is NULL
- ; If a new item could not be allocated, the return value is -1
- ;========================================================================================
-
- _FW_PrivWinGetTaskGlobals:
-
- ; get the task ID, placed at the top to improve caching on i486
- mov AX, SS
-
- if LPTR
- ; establish the DS
- mov DX, _DATA
- push DS
- mov DS, DX
- endif
-
- ; see if the task ID is the same as the cached one
- cmp AX, WORD PTR [gCachedTaskID]
- jne @@doSearch
-
- ; it is, just return the cached value
- mov AX, WORD PTR [gCachedTaskGPtr]
- mov DX, WORD PTR [gCachedTaskGPtr + 2]
-
- ; restore the DS and return
- ; do not jump to the end: that flushes the instruction cache
- if LPTR
- pop DS
- endif
- retf
-
- ; search the table
- @@doSearch:
- push DI ; routines need to preserve SI and DI
-
- mov DX, DS ; scasw buffer is pointed by ES:DI
- mov CX, [gTaskCount]
- mov ES, DX
- mov DI, OFFSET gTaskIDArray
- cld ; search forward
- repnz scasw
- jnz @@addNewTaskId
-
- ; the task is in the table, and DI points one past the entry
- mov gCachedTaskID, AX
- sub DI, OFFSET gTaskIDArray + 2
- shl DI, 2
- mov AX, WORD PTR ES:gTaskPtrArray[DI]
- mov DX, WORD PTR ES:gTaskPtrArray + 2[DI]
- jmp short @@cacheAndReturn
-
- ; the task is not in the table, add a new one
- @@addNewTaskId:
- cmp [gTaskCount], kMaxTasks
- jne @@nowAddTask
- call PackTaskTable
- cmp [gTaskCount], kMaxTasks
- je @@tooManyTasks
-
- @@nowAddTask:
- mov ES:[DI], AX
- mov gCachedTaskID, AX
- sub DI, OFFSET gTaskIDArray
- shl DI, 2
- xor AX, AX ; the initial data pointer value is 0
- mov DX, AX
- mov WORD PTR ES:gTaskPtrArray[DI], AX
- mov WORD PTR ES:gTaskPtrArray + 2[DI], DX
- inc [gTaskCount]
- jmp short @@cacheAndReturn
-
- ; too many tasks, return ((void*) -1)
- @@tooManyTasks:
- xor AX, AX
- dec AX
- mov DX, AX
- jmp short @@returnAXDX
-
- ; store the value in the cache and return
- @@cacheAndReturn:
- mov WORD PTR [gCachedTaskGPtr], AX
- mov WORD PTR [gCachedTaskGPtr + 2], DX
-
- ; restore registers
- @@returnAXDX:
- pop DI
- if LPTR
- pop DS
- endif
-
- ; return
- retf
-
- ;========================================================================================
- ; FW_PrivWinSetTaskGlobals:
- ; Sets the global pointer associated with this task
- ;
- ; Parameters:
- ; The data pointer to associate with the current task
- ;
- ; Return value:
- ; 1 if everything is kosher
- ; 0 if the current task is not in the table yet
- ;========================================================================================
-
- _FW_PrivWinSetTaskGlobals PROC
- ARG dataArg:DWORD
-
- WINENTER
-
- ; save registers
- push DI
-
- ; BX holds the return value
- xor BX, BX
-
- ; get the task ID
- mov AX, SS
-
- mov CX, [gTaskCount]
- mov DX, DS ; scasw buffer is pointed by ES:DI
- mov ES, DX
- mov DI, OFFSET gTaskIDArray
- cld ; search forward
- repnz scasw
- jnz @@doReturn
-
- ; the search is successfull, ES:DI points one past the found entry
- sub DI, OFFSET gTaskIDArray + 2
- shl DI, 2
- mov AX, WORD PTR [dataArg]
- mov DX, WORD PTR [dataArg + 2]
- mov WORD PTR ES:gTaskPtrArray[DI], AX
- mov WORD PTR ES:gTaskPtrArray + 2[DI], DX
-
- ; invalidate the cache
- mov gCachedTaskID, 0
-
- ; return a value indicating success
- inc BX
-
- ; restore registers and return
- @@doReturn:
- pop DI
- mov AX, BX ; put return value into AX
-
- WINLEAVE
- retf
-
- _FW_PrivWinSetTaskGlobals ENDP
-
- endcode FWLookup
- end
-
-